﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.InfoCardPolicy
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.Collections.Generic;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.Xml;
using System.Xml.Schema;

namespace Microsoft.InfoCards
{
  internal class InfoCardPolicy
  {
    private static XmlNamespaceManager m_defNamespaces = XmlNames.CreateNamespaceManager((XmlNameTable) new NameTable());
    private string m_privacyPolicyLink = string.Empty;
    private EndpointAddress m_issuer;
    private uint m_privacyPolicyVersion;
    private bool m_isManaged;
    private bool m_requiresManagedCard;
    private RecipientIdentity m_immediateTokenRecipientIdentity;
    private RecipientIdentity m_recipientIdentity;
    private Policy m_policyPrimary;
    private Policy m_policySecondary;
    private Policy m_policyMerged;
    private readonly PolicyUsageContext m_policyUsageContext;

    public InfoCardPolicy(
      EndpointAddress immediateTokenRecipient,
      EndpointAddress issuer,
      ParsedPolicy policy,
      PolicyUsageContext policyUsageContext,
      string privacyUrl,
      uint privacyVersion,
      RecipientIdentity recipientIdentity,
      bool isManaged)
    {
      this.m_policyUsageContext = policyUsageContext;
      this.m_issuer = issuer;
      this.m_recipientIdentity = recipientIdentity;
      this.m_immediateTokenRecipientIdentity = RecipientIdentity.CreateIdentity(immediateTokenRecipient, false);
      this.m_isManaged = isManaged;
      if (policy != null)
        this.ParseIncomingPolicy(policy);
      if (!InfoCardPolicy.IsSelfIssuedUriPresent(this.m_issuer) && issuer != (EndpointAddress) null && !Utility.CompareUri(issuer.Uri, new Uri("http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous")))
        this.m_requiresManagedCard = true;
      this.m_privacyPolicyLink = privacyUrl;
      this.m_privacyPolicyVersion = privacyVersion;
    }

    private void ParseIncomingPolicy(ParsedPolicy parsedPolicy)
    {
      if (PolicyType.Composite == parsedPolicy.PolicyType)
      {
        try
        {
          this.m_policyPrimary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml(parsedPolicy.PolicyXmlPrimary);
          this.m_policySecondary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml(parsedPolicy.PolicyXmlSecondary);
          this.m_policyMerged = Policy.CreateMergedPolicy(parsedPolicy.PolicyXmlOriginal, this.m_policyPrimary, this.m_policySecondary);
        }
        catch (XmlSchemaValidationException ex)
        {
          throw InfoCardTrace.ThrowHelperError((Exception) new PolicyValidationException(SR.GetString("SchemaValidationFailed"), (Exception) ex));
        }
      }
      else if (parsedPolicy.PolicyType == PolicyType.PrimaryOnly)
      {
        try
        {
          this.m_policyPrimary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml(parsedPolicy.PolicyXmlPrimary);
          this.m_policyMerged = this.m_policyPrimary;
        }
        catch (XmlSchemaValidationException ex)
        {
          throw InfoCardTrace.ThrowHelperError((Exception) new PolicyValidationException(SR.GetString("SchemaValidationFailed"), (Exception) ex));
        }
      }
      else
      {
        if (PolicyType.SecondaryOnly != parsedPolicy.PolicyType)
          return;
        try
        {
          this.m_policySecondary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml(parsedPolicy.PolicyXmlSecondary);
          this.m_policyMerged = this.m_policySecondary;
        }
        catch (XmlSchemaValidationException ex)
        {
          throw InfoCardTrace.ThrowHelperError((Exception) new PolicyValidationException(SR.GetString("SchemaValidationFailed"), (Exception) ex));
        }
      }
    }

    public Policy MergedPolicy
    {
      get
      {
        return this.m_policyMerged;
      }
    }

    public string RequestType
    {
      get
      {
        return this.m_policyMerged.RequestType;
      }
    }

    public Policy ClientPolicy
    {
      get
      {
        return this.m_policyPrimary;
      }
    }

    public Policy RelyingPartyPolicy
    {
      get
      {
        return this.m_policySecondary;
      }
    }

    public OptionalRstParameters OptionalRstParams
    {
      get
      {
        return this.m_policyMerged.OptionalRstParams;
      }
    }

    public string[] RequiredClaims
    {
      get
      {
        return this.m_policyMerged.RequiredClaims;
      }
    }

    public string[] OptionalClaims
    {
      get
      {
        return this.m_policyMerged.OptionalClaims;
      }
    }

    public SecurityKeyTypeInternal KeyType
    {
      get
      {
        return this.m_policyMerged.KeyType;
      }
    }

    public bool KeyTypeSpecified
    {
      get
      {
        return this.m_policyMerged.KeyTypeSpecified;
      }
    }

    public EndpointAddress PolicyAppliesTo
    {
      get
      {
        return this.m_policyMerged.PolicyAppliesTo;
      }
    }

    public MemoryStream UnprocessedPolicyElements
    {
      get
      {
        return this.m_policyMerged.UnprocessedPolicyElements;
      }
    }

    public bool KeySizeSpecified
    {
      get
      {
        return this.m_policyMerged.KeySizeSpecified;
      }
    }

    public uint KeySize
    {
      get
      {
        return this.m_policyMerged.KeySize;
      }
    }

    public bool NonWhiteListElementsFound
    {
      get
      {
        return this.m_policyMerged.NonWhiteListElementsFound;
      }
    }

    public List<string> NonWhiteListElements
    {
      get
      {
        return this.m_policyMerged.NonWhiteListElements;
      }
    }

    public ProtocolProfile ProtocolVersionProfile
    {
      get
      {
        return this.m_policyMerged.ProtocolVersionProfile;
      }
    }

    public RecipientIdentity ImmediateTokenRecipient
    {
      get
      {
        return this.m_immediateTokenRecipientIdentity;
      }
    }

    public EndpointAddress Issuer
    {
      get
      {
        return this.m_issuer;
      }
    }

    public RecipientIdentity Recipient
    {
      get
      {
        return this.m_recipientIdentity;
      }
    }

    public uint GetIntelligentKeySize(bool isSelfIssuedCardSelected)
    {
      if (isSelfIssuedCardSelected)
        throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException());
      if (SecurityKeyTypeInternal.AsymmetricKey == this.KeyType)
        return 2048;
      if (this.KeyType == SecurityKeyTypeInternal.SymmetricKey)
      {
        if (!this.KeySizeSpecified)
          return (uint) SecurityAlgorithmSuite.Default.DefaultSymmetricKeyLength;
        return this.KeySize;
      }
      InfoCardTrace.Assert(false, "Should access this property only in managed card non-no proof key scenario");
      throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException());
    }

    public string GetKeyTypeString()
    {
      switch (this.KeyType)
      {
        case SecurityKeyTypeInternal.SymmetricKey:
          return this.m_policyMerged.ProtocolVersionProfile.WSTrust.KeyTypeSymmetric.ToString();
        case SecurityKeyTypeInternal.AsymmetricKey:
          return this.m_policyMerged.ProtocolVersionProfile.WSTrust.KeyTypeAsymmetric.ToString();
        case SecurityKeyTypeInternal.NoKey:
          return this.m_policyMerged.ProtocolVersionProfile.WSTrust.KeyTypeBearer.ToString();
        default:
          InfoCardTrace.Assert(false, "Impossible condition in code");
          throw InfoCardTrace.ThrowHelperError((Exception) new InvalidOperationException());
      }
    }

    public string PrivacyPolicyLink
    {
      get
      {
        return this.m_privacyPolicyLink;
      }
    }

    public uint PrivacyPolicyVersion
    {
      get
      {
        return this.m_privacyPolicyVersion;
      }
    }

    public bool IsManaged
    {
      get
      {
        return this.m_isManaged;
      }
    }

    public bool RequiresManagedCard
    {
      get
      {
        return this.m_requiresManagedCard;
      }
    }

    public bool RequiresSelfIssuedCard
    {
      get
      {
        if ((EndpointAddress) null == this.m_issuer)
          return false;
        return Utility.CompareUri(this.m_issuer.Uri, new Uri("http://schemas.xmlsoap.org/ws/2005/05/identity/issuer/self"));
      }
    }

    public void SetRecipientInfo(
      RecipientIdentity recipientIdentity,
      string privacyUrl,
      uint privacyVersion)
    {
      this.m_recipientIdentity = recipientIdentity;
      this.m_privacyPolicyLink = privacyUrl;
      this.m_privacyPolicyVersion = privacyVersion;
    }

    private void ComputeRequiresManagedCardFlag()
    {
      if (this.m_policyMerged.NonWhiteListElementsFound)
        this.m_requiresManagedCard = true;
      foreach (string requiredClaim in this.m_policyMerged.RequiredClaims)
      {
        if (!PolicyUtility.IsSelfIssuedClaim(requiredClaim))
          this.m_requiresManagedCard = true;
      }
      if (!string.IsNullOrEmpty(this.m_policyMerged.OptionalRstParams.TokenType) && !PolicyUtility.IsSelfIssuedTokenType(this.m_policyMerged.OptionalRstParams.TokenType))
        this.m_requiresManagedCard = true;
      if (!(this.m_immediateTokenRecipientIdentity is X509RecipientIdentity) && this.m_policyMerged.KeyType == SecurityKeyTypeInternal.SymmetricKey)
        this.m_requiresManagedCard = true;
      if (string.IsNullOrEmpty(this.m_policyMerged.OptionalRstParams.KeyWrapAlgorithm) || !(this.m_policyMerged.OptionalRstParams.KeyWrapAlgorithm != SecurityAlgorithmSuite.Default.DefaultAsymmetricKeyWrapAlgorithm))
        return;
      this.m_requiresManagedCard = true;
    }

    private void FillComputedPolicy()
    {
      this.ComputeRequiresManagedCardFlag();
    }

    public void Validate()
    {
      bool flag = this.m_policyMerged.RequiredClaims == null || 0 == this.m_policyMerged.RequiredClaims.Length;
      PolicyValidator policyValidator;
      if (this.m_policyUsageContext == PolicyUsageContext.Browser)
      {
        if (flag)
          throw InfoCardTrace.ThrowHelperError((Exception) new PolicyValidationException(SR.GetString("NoClaimsFoundInPolicy")));
        this.FillComputedPolicy();
        policyValidator = (PolicyValidator) new BrowserPolicyValidator(this);
      }
      else if (PolicyUsageContext.GetToken == this.m_policyUsageContext)
      {
        if (flag)
          throw InfoCardTrace.ThrowHelperError((Exception) new PolicyValidationException(SR.GetString("NoClaimsFoundInPolicy")));
        this.FillComputedPolicy();
        policyValidator = new PolicyValidator(this);
      }
      else
        policyValidator = (PolicyValidator) new IntermediatePolicyValidator(this);
      policyValidator.Validate();
    }

    public void ThrowIfNonPpidClaimsPresent()
    {
      InfoCardTrace.ThrowInvalidArgumentConditional(this.m_policyMerged.RequiredClaims == null || this.m_policyMerged.OptionalClaims == null, "claims");
      if (this.m_policyMerged.RequiredClaims.Length != 1 || !(this.m_policyMerged.RequiredClaims[0] == InfoCardConstants.PPIDClaimsUri) || this.m_policyMerged.OptionalClaims.Length != 0)
        throw InfoCardTrace.ThrowHelperError((Exception) new PolicyValidationException(SR.GetString("IPStsPolicyRequestingNonPpidClaims")));
    }

    public static bool IsSelfIssuedUriPresent(EndpointAddress address)
    {
      return !((EndpointAddress) null == address) && Utility.CompareUri(address.Uri, XmlNames.WSIdentity.SelfIssuerUriValue);
    }
  }
}
